package com.tlxch.utils;

import com.tlxch.constant.Message;
import com.tlxch.dto.LearnModeldto;
import com.tlxch.dto.Sattitudedto;
import com.tlxch.dto.Seffectdto;
import com.tlxch.dto.Shabitdto;
import com.tlxch.vo.AssessMsgvo;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

// 学生评估工具类（单例模式）
public class StudentEvaluationUtils {
    private static final StudentEvaluationUtils INSTANCE = new StudentEvaluationUtils();
    private static final Map<String, Integer> TIME_UNIT_MAP = initTimeUnitMap();

    // 预设关键词库
    private static final List<String> POSITIVE_WORDS = Arrays.asList(
            "积极", "认真", "高效", "进步", "主动", "坚持", "热情", "扎实"
    );
    private static final List<String> NEGATIVE_WORDS = Arrays.asList(
            "拖延", "敷衍", "缺交", "退步", "被动", "放弃", "粗心", "低效"
    );

    private StudentEvaluationUtils() {}

    public static StudentEvaluationUtils getInstance() {
        return INSTANCE;
    }

    // 初始化时间单位映射
    private static Map<String, Integer> initTimeUnitMap() {
        Map<String, Integer> map = new HashMap<>();
        map.put("天", 1);
        map.put("周", 7);
        map.put("月", 30);
        map.put("学期", 180);
        map.put("年", 365);
        return Collections.unmodifiableMap(map);
    }

    // 评估学生方法
    public AssessMsgvo evaluateStudent(LearnModeldto request) {
        // 1. 处理文字描述信息
        double teacherScore = evaluateText(request.getSgTappraise());
        double habitDescScore = 0;
        double habitFreqScore = 0;
        double habitDurationScore =0;
        for (Shabitdto shabitdto : request.getShabitdtos()) {
            habitDescScore += evaluateText(shabitdto.getShHcontent());
            habitFreqScore += evaluateHabitFrequency(shabitdto.getShFrequency());
            habitDurationScore = evaluateHabitDuration(
                    shabitdto.getShCreatetime(),
                    shabitdto.getShDuration()
            );
        }
        habitFreqScore = habitFreqScore/request.getShabitdtos().size();
        double attitudeDescScore =0;
        double attitudeRating = 0;
        for (Sattitudedto sattitudedto : request.getSattitudedtos()) {
            attitudeDescScore += evaluateText(sattitudedto.getSaAcontent());
            attitudeRating += normalizeScore(sattitudedto.getSaScore(),5);
        }
        double effectDescScore =0;
        double effectRating = 0;
        for (Seffectdto seffectdto : request.getSeffectdtos()) {
            effectDescScore += evaluateText(seffectdto.getSeContent());
            effectRating += normalizeScore(seffectdto.getSeScore(),5);
        }
        // 2. 处理习惯频率


        // 3. 处理习惯持续时间



        // 4. 处理数值信息
        double courseScore = normalizeScore(request.getSgGrades(), 100);
        double dailyScore = normalizeScore(request.getSgPgrades(), 100);

        double entranceScore = normalizeScore(request.getSMgrades(), 100);

        // 5. 计算综合得分
        double textTotal = calculateTextTotal(
                teacherScore, habitDescScore, attitudeDescScore,
                effectDescScore, habitFreqScore, habitDurationScore
        );

        double numericTotal = calculateNumericTotal(
                courseScore, dailyScore, attitudeRating,
                effectRating, entranceScore
        );
        AssessMsgvo assessMsg = new AssessMsgvo();
        double finalScore = textTotal + numericTotal;
        if (finalScore >= 8) {
            assessMsg.setTsLevel(1);
            assessMsg.setTsContent(Collections.singletonList(Message.very_good));
        }else if (finalScore >= 6) {
            assessMsg.setTsLevel(2);
            assessMsg.setTsContent(Collections.singletonList(Message.good));
        }else if (finalScore >= 4) {
            assessMsg.setTsLevel(3);
            assessMsg.setTsContent(Collections.singletonList(Message.concern));
        }else {
            assessMsg.setTsLevel(4);
            assessMsg.setTsContent(Collections.singletonList(Message.warn));
        }
        assessMsg.setTsScore(finalScore);
        return assessMsg;
    }

    // 文字描述评估
    private double evaluateText(String text) {
        if (text == null || text.trim().isEmpty()) {
            return 5.0; // 默认中等水平
        }

        // 关键词匹配
        int positiveCount = countWords(text, POSITIVE_WORDS);
        int negativeCount = countWords(text, NEGATIVE_WORDS);

        // 情感分析（简化版）
        double sentimentScore = analyzeSentiment(text);

        // 计算总分（-10到10分之间）
        double rawScore = (positiveCount - negativeCount) * 2 + sentimentScore;

        // 归一化到0-10分
        return Math.max(0, Math.min(10, rawScore + 5));
    }

    // 计算文本中关键词出现次数
    private int countWords(String text, List<String> words) {
        int count = 0;
        for (String word : words) {
            count += text.split(word).length - 1;
        }
        return count;
    }

    // 情感分析（简化版）
    private double analyzeSentiment(String text) {
        if (text.contains("优秀") || text.contains("进步") || text.contains("高效")) {
            return 3.0; // 积极
        } else if (text.contains("一般") || text.contains("正常") || text.contains("中等")) {
            return 0.0; // 中性
        } else if (text.contains("不足") || text.contains("需要改进") || text.contains("退步")) {
            return -3.0; // 消极
        }
        return 0.0; // 默认中性
    }

    // 评估习惯频率
    private double evaluateHabitFrequency(String frequencyText) {
        if (frequencyText == null || frequencyText.trim().isEmpty()) {
            return 0.0;
        }

        // 提取频率数值
        Pattern pattern = Pattern.compile("(\\d+)");
        Matcher matcher = pattern.matcher(frequencyText);

        if (matcher.find()) {
            int frequency = Integer.parseInt(matcher.group(1));
            // 假设最高频率为10次/天，归一化到0-10分
            return normalizeScore(frequency, 10);
        }

        return 0.0;
    }

    // 评估习惯持续时间
    private double evaluateHabitDuration(String startTime, String durationText) {
        try {
            // 解析开始日期
            LocalDate startDate = LocalDate.parse(startTime, DateTimeFormatter.ISO_LOCAL_DATE);
            LocalDate currentDate = LocalDate.now();

            // 计算实际天数
            long actualDays = ChronoUnit.DAYS.between(startDate, currentDate);

            // 解析描述中的天数
            long describedDays = parseDurationText(durationText);

            // 取较小值（避免描述与实际不符）
            long effectiveDays = Math.min(actualDays, describedDays);

            // 归一化到0-10分（假设最长持续365天）
            return normalizeScore(effectiveDays, 365);

        } catch (Exception e) {
            // 解析失败时返回0
            return 0.0;
        }
    }

    // 解析持续时间文本
    private long parseDurationText(String durationText) {
        if (durationText == null || durationText.trim().isEmpty()) {
            return 0;
        }

        // 提取数字和单位
        Pattern pattern = Pattern.compile("(\\d+)(.*)");
        Matcher matcher = pattern.matcher(durationText);

        if (matcher.find()) {
            int number = Integer.parseInt(matcher.group(1));
            String unit = matcher.group(2).trim();

            return number * TIME_UNIT_MAP.getOrDefault(unit, 0);
        }

        return 0;
    }

    // 数值归一化
    private double normalizeScore(double score, double maxScore) {
        if (maxScore <= 0) {
            return 5.0; // 避免除零错误
        }
        return Math.min(10.0, (score / maxScore) * 10);
    }

    // 计算文字描述总分
    private double calculateTextTotal(
            double teacherScore, double habitDescScore, double attitudeDescScore,
            double effectDescScore, double habitFreqScore, double habitDurationScore
    ) {
        return (teacherScore * 0.2      // 教师评价权重
                + habitDescScore * 0.1    // 习惯描述权重
                + attitudeDescScore * 0.2 // 态度描述权重
                + effectDescScore * 0.2   // 效果描述权重
                + habitFreqScore * 0.1    // 习惯频率权重
                + habitDurationScore * 0.2) // 习惯持续时间权重
                * 0.4; // 文字类整体权重
    }

    // 计算数值信息总分
    private double calculateNumericTotal(
            double courseScore, double dailyScore,
            double attitudeRating, double effectRating, double entranceScore
    ) {
        return (courseScore * 0.3       // 课程成绩权重
                + dailyScore * 0.2        // 平时分权重
                + attitudeRating * 0.2    // 态度评分权重
                + effectRating * 0.2      // 效果评分权重
                + entranceScore * 0.1)    // 入学成绩权重
                * 0.6; // 数值类整体权重
    }
}
